#include "Common.h"
#include "Logger.h"
#include <stdarg.h>

using namespace RayFrame;

IMPL_SINGLETON(Logger);

void Logger::AddPolicy(STRING filename, LogPolicy* policy)
{
  m_policies.push_back(policy);
  
  policy->Create(filename);
  m_isOK = m_isOK && policy->IsOK();
}

#define r_INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define rva_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

void Logger::Write(LogLevel level, const char* format, ...)
{
  char buffer[BUFFER_LENGTH];
  va_list arglist;

  va_start(arglist, format);
  vsprintf(buffer, format, arglist);
  va_end(arglist);

  if(level < m_logLevel)
    return;

  for(IterPolicy iter = m_policies.begin();
    iter != m_policies.end();
    iter ++)
  {
    (*iter)->Write(buffer, level);
  }
}

void Logger::WriteBanner(const char* format, ...)
{
  char buffer[BUFFER_LENGTH];
  va_list argptr;
  va_start(argptr, format);
  vsprintf(buffer, format, argptr);
  va_end(argptr);

  for(IterPolicy iter = m_policies.begin();
    iter != m_policies.end();
    iter ++)
  {
    (*iter)->WriteBanner(buffer);
  }
}

void Logger::Warning(const char* format, ...)
{
  char buffer[BUFFER_LENGTH];
  va_list argptr;
  va_start(argptr, format);
  vsprintf(buffer, format, argptr);
  va_end(argptr);

  Write(LogHigher, "Warning: %s", buffer);
}

void Logger::Error(const char* format, ...)
{
  char buffer[BUFFER_LENGTH];
  va_list argptr;
  va_start(argptr, format);
  vsprintf(buffer, format, argptr);
  va_end(argptr);

  Write(LogHigher, "Error: %s", buffer);
}

void Logger::Fatal(const char* format, ...)
{
  char buffer[BUFFER_LENGTH];
  va_list argptr;
  va_start(argptr, format);
  vsprintf(buffer, format, argptr);
  va_end(argptr);

  Write(LogHigher, "Fatal: %s", buffer);
  assert(false);
}

void Logger::Destroy()
{
  internalDestroy();
}

void Logger::internalCreate()
{
  
}

void Logger::internalDestroy()
{
  for( IterPolicy iter = m_policies.begin();
    iter != m_policies.end();
    iter ++)
  {
    (*iter)->Destroy();
    delete (*iter);
  }
}
